<script setup>
import {ref, onMounted, nextTick} from 'vue'
import {message} from 'ant-design-vue'
import {useLoginUserStore} from "@/stores/useLoginUserStore.js";
import router from "@/router/index.js";
import {fetchEventSource} from "@microsoft/fetch-event-source";

const messages = ref([
  {
    role: 'assistant',
    content: '泥嚎呀，我是厚米AI，是你学习和生活中的智能助手๑>ᴗ<๑)♡，你可以向我提问任何问题，欢迎提问 (´▽`ʃƪ)🎉。'
  }
])

const inputMessage = ref('')
const isTyping = ref(false)          // 控制“AI正在输入”动画
const controller = ref(null)

const userAvatar = 'https://picsum.photos/id/64/200 '
const aiAvatar = 'https://picsum.photos/id/1005/200 '

const sendMessage = async () => {
  if (!inputMessage.value.trim()) return

  // 1. 追加用户消息
  messages.value.push({role: 'user', content: inputMessage.value})
  inputMessage.value = ''
  await nextTick()
  scrollToBottom()

  // 2. 打开“正在输入”动画
  isTyping.value = true

  // 3. 创建 AbortController
  controller.value = new AbortController()

  try {
    let firstPacket = true               // 首包标记
    let aiMessageIndex = messages.value.length
    let aiResponse = ''

    await fetchEventSource('http://localhost:8123/api/ai/chat/stream', {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify({messages: messages.value.slice(-8)}),
      signal: controller.value.signal,
      credentials: 'include',
      openWhenHidden: false,
      retryInterval: undefined, // 禁用重试
      maxRetries: 0,            // 禁用重试次数
      onmessage(ev) {
        const {data} = JSON.parse( ev.data)
        // 处理 delta 事件（对应后端的 .name("delta")）
        if (ev.event === 'delta') {
          console.log('接收到数据:', data);
          // 在这里更新UI显示
          if(firstPacket){
            messages.value.push({role: 'assistant', content: ''})
            isTyping.value = false
            firstPacket = false
          }

          messages.value[aiMessageIndex].content+= data
          scrollToBottom()
          // aiResponse += ev.data
          // messages.value[aiMessageIndex].content = aiResponse
        }
        // 处理完成事件（如果后端取消注释）
        else if (ev.event === 'done' && data === '[DONE]') {
          console.log('数据接收完成');
          controller.value?.abort()
        }
        // 处理错误事件
        else if (ev.event === 'error') {
          console.error('服务器错误:', ev.data);
          controller.value?.abort()
        }
      },
      onerror(err) {
        console.error('连接错误:', err);
        controller.value?.abort()
        throw err;
      }
    });
  } catch (e) {
    message.error('网络错误')
    controller.value?.abort()
  } finally {
    isTyping.value = false
    controller.value = null
    scrollToBottom()
  }


  // try {
  //   const response = await fetch('http://localhost:8123/api/ai/chat/stream', {
  //     method: 'POST',
  //     headers: {'Content-Type': 'application/json'},
  //     body: JSON.stringify({messages: messages.value.slice(-7)}),
  //     signal: controller.value.signal,
  //     credentials: 'include'
  //   })
  //
  //   if (!response.ok) {
  //     message.error('发送消息错误')
  //     isTyping.value = false
  //     return
  //   }
  //
  //   // 4. 流式读取
  //   const reader = response.body.getReader()
  //   const decoder = new TextDecoder()
  //   let aiResponse = ''
  //   let aiMessageIndex = messages.value.length
  //   let firstPacket = true               // 首包标记

  // 先占个位
  // messages.value.push({role: 'assistant', content: ''})


  // while (true) {
  //   const {done, value} = await reader.read()
  //   if (done) break
  //
  //   const chunk = decoder.decode(value, {stream: true})
  //   console.log('chunk:\n', chunk)
  //   const lines = chunk.split('\n')
  //
  //   for (const line of lines) {
  //     const trim = line.trim()
  //     if (trim.startsWith('data:')) {
  //       const data = trim.slice(5).trim()
  //       // if (data === '[DONE]') break
  //
  //       // 首包到达即关闭动画
  //       if (firstPacket) {
  //         if (data === '') {
  //           continue
  //         }
  //         isTyping.value = false
  //         firstPacket = false
  //         messages.value.push({role: 'assistant', content: ''})
  //       }
  //
  //       aiResponse += data
  //       messages.value[aiMessageIndex].content = aiResponse
  //       await nextTick()
  //       scrollToBottom()
  //     }
  //   }
  // }
  // } catch (err) {
  //   if (err.name !== 'AbortError') {
  //     console.error(err)
  //     message.error('网络错误')
  //   }
  // } finally {
  //   isTyping.value = false
  //   controller.value = null
  //   scrollToBottom()
  // }
}

function scrollToBottom() {
  nextTick(() => {
    const box = document.querySelector('.message-list')
    box && (box.scrollTop = box.scrollHeight)
  })
}

onMounted(() => {
  const loginUserStore = useLoginUserStore();
  if (loginUserStore.loginUser.id == null) {
    message.error('请先登录')
    router.replace("/login")
  }
  scrollToBottom()

})
</script>

<template>
  <div class="chat-page">
    <header class="chat-header"/>

    <main class="chat-container">
      <div class="message-list">
        <div
            v-for="(msg, idx) in messages"
            :key="idx"
            :class="['message-item', msg.role === 'user' ? 'user-message' : 'ai-message']"
        >
          <div class="avatar">
            <img :src="msg.role === 'user' ? userAvatar : aiAvatar" alt="avatar"/>
          </div>
          <div class="message-bubble">
            <p>{{ msg.content }}</p>
          </div>
        </div>

        <!-- 正在输入动画 -->
        <div class="message-item ai-message typing-indicator" v-if="isTyping">
          <div class="avatar">
            <img :src="aiAvatar" alt="ai-avatar"/>
          </div>
          <div class="message-bubble typing">
            <span class="dot"/>
            <span class="dot"/>
            <span class="dot"/>
          </div>
        </div>
      </div>
    </main>

    <footer class="input-area">
      <a-textarea
          v-model:value="inputMessage"
          placeholder="请输入您的问题..."
          :rows="1"
          auto-size
          @keyup.enter="sendMessage"
          class="message-input"
      />
      <a-button
          type="primary"
          @click="sendMessage"
          class="send-button"
          :disabled="!inputMessage.trim()"
      >
        <a-icon type="paper-plane"/>
      </a-button>
    </footer>
  </div>
</template>

<style scoped>
/* 仅把高度改成 85vh，其余样式保持你原文件 */
.chat-page {
  display: flex;
  flex-direction: column;
  height: 85vh;
  background-color: #f8fafc;
  overflow: hidden;
}

.chat-header {
  color: #64748b;
  padding: 8px 0;
  text-align: center;
}

.chat-container {
  flex: 1;
  max-width: 800px;
  width: 100%;
  margin: 0 auto;
  padding: 16px;
  overflow: hidden;
}

.message-list {
  height: 100%;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding-right: 10px;
}

.message-item {
  display: flex;
  max-width: 75%;
}

.ai-message {
  align-self: flex-start;
}

.user-message {
  align-self: flex-end;
  flex-direction: row-reverse;
}

.avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  overflow: hidden;
  flex-shrink: 0;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.message-bubble {
  padding: 10px 16px;
  border-radius: 16px;
  word-wrap: break-word;
  line-height: 1.5;
  font-size: 0.95rem;
}

.ai-message .message-bubble {
  background-color: white;
  color: #334155;
  border-top-left-radius: 4px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.07);
  margin-left: 10px;
}

.user-message .message-bubble {
  background-color: #3b82f6;
  color: white;
  border-top-right-radius: 4px;
  box-shadow: 0 1px 4px rgba(59, 130, 246, 0.2);
  margin-right: 10px;
}

.input-area {
  display: flex;
  gap: 10px;
  padding: 12px 16px;
  background-color: white;
  border-top: 1px solid #e2e8f0;
  max-width: 800px;
  width: 100%;
  margin: 0 auto;
  box-sizing: border-box;
}

.message-input {
  flex: 1;
  border-radius: 20px;
  padding: 10px 16px;
  border: 1px solid #e2e8f0;
  transition: all 0.3s ease;
  font-size: 0.95rem;
}

.message-input:focus {
  border-color: #3b82f6;
  box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
  outline: none;
}

.send-button {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  padding: 0;
  background-color: #3b82f6;
  border: none;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  justify-content: center;
}

.send-button:hover {
  transform: scale(1.05);
  box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3);
  background-color: #2563eb;
}

.send-button:disabled {
  background-color: #cbd5e1;
  transform: none;
  box-shadow: none;
  cursor: not-allowed;
}

.typing-indicator {
  align-self: flex-start;
}

.typing {
  display: flex;
  gap: 5px;
  padding: 10px 16px;
}

.typing .dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: #94a3b8;
  animation: typing 1.4s infinite ease-in-out both;
}

.typing .dot:nth-child(1) {
  animation-delay: -0.32s;
}

.typing .dot:nth-child(2) {
  animation-delay: -0.16s;
}

@keyframes typing {
  0%, 80%, 100% {
    transform: scale(0);
  }
  40% {
    transform: scale(1);
  }
}

.message-list::-webkit-scrollbar {
  width: 5px;
}

.message-list::-webkit-scrollbar-track {
  background: transparent;
}

.message-list::-webkit-scrollbar-thumb {
  background-color: rgba(148, 163, 184, 0.4);
  border-radius: 3px;
}

.message-list::-webkit-scrollbar-thumb:hover {
  background-color: rgba(148, 163, 184, 0.7);
}
</style>
